[ GET ] api/products/{product} 對應到的是 ProductController 的 show 方法
有找到資料會回傳特定的產品資料。
/**
* Display the specified resource.
* 查詢特定 ID 的產品資料
*/
public function show(Product $product)
{
// 回傳特定產品資料
return response(new ProductResource($product), Response::HTTP_OK);
}
顯示 200 狀態碼及產品資料,所以測試成功!
這個方法主要是用來取得單一產品的詳細資料,這通常是在 API 裡 GET /products/{id} 這樣的路由使用,負責回傳單一產品的內容。
在我的 Controller & Route:來指派店長跟分配店員吧! 文章裡有提到:
我要分配給一位自帶分身術的店員,承攬所有引導工作。
就是 Laravel 的內建方法:apiResource
可以把 URI 自動對應到 ProductController 內相對應的方法。
Route::apiResource('products', ProductController::class);
那如果不是使用 apiResource 自動對應,原本此路徑分配的路由應該是長這樣子:
Route::get('/products/{product}', [ProductController::class, 'show']);
Laravel 提供了一個很方便的功能叫 Route Model Binding,意思就是它會自動根據 URL 上的 id 去資料庫抓出相對應的產品資料,然後傳進這個方法裡。
例如:
當你訪問 GET /products/1,它會自動幫你找到 id 是 1 的產品,然後這個產品資料就會被當成參數 $product。
將 $product 資料建立一個新的 ProductResource 物件。
而且這個資源物件會把我們的產品資料轉換成 JSON 格式。
簡單來說,ProductResource 就是負責把產品資料變成前端比較容易處理的格式,這樣 API 回傳的資料會更有一致性。
這是 Laravel 提供的一個非常方便的功能!
當你使用 Route Model Binding 時,Laravel 會根據 URL 上的 ID 或其他參數,從資料庫中找到對應的模型物件(例如一筆商品資料),然後自動把它傳遞到控制器的方法裡。
而 Route Model Binding 又分為:
上述做的查詢單一產品資料範例就是使用 Implicit Binding。
菜雞仔如我,覺得 Implicit Binding 就是最方便的XDDD
URL 參數名稱必須與控制器方法中的參數名稱相同,且該參數對應的模型名稱與 URL 中的參數名稱也要一致!
例如: {product} 對應 Product 模型。
Laravel 會根據模型的主鍵(預設為 id)自動查詢。
有時候你可能希望用非主鍵來進行查詢,或是需要自定義查詢邏輯,這時就可以使用 Explicit Binding。
假設我們希望用商品的 slug 而不是 id 來查詢商品,那可以這樣設定:
Route::get('/products/{product:slug}', [ProductController::class, 'show']);
我們告訴 Laravel 請根據 slug 欄位來查詢對應的商品,而不是預設的 id。
如果你需要完全自定義的查詢邏輯,可以在 RouteServiceProvider 中手動定義:
use App\Models\Product;
public function boot()
{
parent::boot();
// 自定義 Route Model Binding
Route::bind('product', function ($value) {
return Product::where('slug', $value)->firstOrFail();
});
}
這樣,當路由中出現 {product} 時,Laravel 就會按照你自定義的查詢邏輯去查詢資料。
可以參考我厲害學姊的文章:Laravel routes
搭配參考官方文件:Laravel Route Model Binding